﻿using LaserMark.Models;
using LaserMark.Extensions;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Windows.Input;

namespace LaserMark.Extensions
{
    public static class ConvertOriginalInfo
    {
        public static OriginalInfo Convert(string fileName)
        {
            using (var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                return Convert(stream);
            }
        }

        public static OriginalInfo Convert(Stream stream)
        {
            var builder = new StringBuilder();
            var pos = new OriginalInfo();

            OPTCache.Values = (Dictionary<string, string?>)OPTRead.Read(stream);
            if (OPTCache.Values != null)
            {
                OPTCache.Values.TryGetValue("Count", out var count);
                var length = System.Convert.ToInt32(count);

                builder.Append(string.Format("{{ \"OriginalCount\": {0}, \"Originals\":[", count));

                for (var i = 1; i <= length; i++)
                {
                    OPTCache.Values.TryGetValue($"Cuttings{i}", out var points);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}XYZW", out var xyzw);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}Pieces", out var price);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}Height", out var height);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}Width", out var width);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}GlassThickness", out var thickness);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}GlassID", out var glassID);
                    builder.Append("{");
                    builder.Append($"\"MaterialQuality\":\"{glassID}\",");
                    builder.Append($"\"Height\":{height},");
                    builder.Append($"\"Width\":{width},");
                    builder.Append($"\"Thickness\":{thickness},");
                    builder.Append($"\"Price\":{price},");
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}TrimLeft", out var trimLeft);
                    OPTCache.Values.TryGetValue($"OPT_Pattern{i}TrimBottom", out var trimBottom);
                    builder.Append($"\"TrimLeft\":{trimLeft},");
                    builder.Append($"\"TrimBottom\":{trimBottom},");

                    if (OPTCache.Values.ContainsKey($"OPT_Pattern{i}TrimTop"))
                    {
                        OPTCache.Values.TryGetValue($"OPT_Pattern{i}TrimTop", out var trimTop);
                        builder.Append($"\"TrimTop\":{trimTop},");
                    }

                    if (OPTCache.Values.ContainsKey($"OPT_Pattern{i}TrimRight"))
                    {
                        OPTCache.Values.TryGetValue($"OPT_Pattern{i}TrimRight", out var trimRight);
                        builder.Append($"\"TrimRight\":{trimRight},");
                    }
                    var infoCount = 1;
                    builder.Append($"\"Infos\":[");
                    while (OPTCache.Values.TryGetValue($"Info{i}{infoCount}ID", out var id))
                    {
                        OPTCache.Values.TryGetValue($"Info{i}{infoCount}SheetWidth", out var sheetWidth);
                        OPTCache.Values.TryGetValue($"Info{i}{infoCount}SheetHeight", out var sheetHeight);
                        builder.Append("{");
                        builder.Append($"\"ID\":{id},\"SheetWidth\":{sheetWidth},\"SheetHeight\":{sheetHeight}");
                        builder.Append("},");
                        infoCount++;

                    }
                    builder.Append($"],");

                    double x = 0;
                    double y = 0;
                    if (xyzw != null)
                    {
                        builder.Append($"\"MarkPoints\":[");
                        var arrPos = xyzw.Split(",");
                        var key = "";
                        var value = "";
                        for (int k = 0; k < arrPos.Length; k++)
                        {
                            if (arrPos[k].Contains("Info"))
                            {
                                key = arrPos[k - 1].Split("=")[0];
                                value = arrPos[k - 1].Split("=")[1];
                                var currnt = arrPos[k].Split(" ")[0].Split("=")[0];
                                if (key == currnt)
                                {
                                    y = System.Convert.ToDouble(value) + System.Convert.ToDouble(arrPos[k].Split(" ")[0].Split("=")[1]);
                                }

                                if (key == "X")
                                {
                                    x += System.Convert.ToDouble(value);
                                }

                                if (key == "Y")
                                {
                                    y += System.Convert.ToDouble(value);
                                }

                                if (key != "Y")
                                {
                                    y = 0;
                                }
                                if (key != "X")
                                {
                                    x = 0;
                                }
                                var count1 = 0;
                                while ((k + count1) < arrPos.Length && arrPos[k + count1].Contains("Info"))
                                {
                                    if (arrPos[k + count1].Split(" ")[0].Split("=")[0] == "Z")
                                    {
                                        x += System.Convert.ToDouble(arrPos[k + count1].Split(" ")[0].Split("=")[1]);
                                    }

                                    if (arrPos[k + count1].Split(" ")[0].Split("=")[0] == "Y")
                                    {
                                        y += System.Convert.ToDouble(arrPos[k + count1].Split(" ")[0].Split("=")[1]);
                                    }

                                    var info = System.Convert.ToInt32(
                                      arrPos[k + count1].Split(" ")[1].Split("=")[1]);
                                    count1++;
                                    builder.Append("{");
                                    OPTCache.Values.TryGetValue($"Info{i}{info}LabelInfo", out var label);
                                    OPTCache.Values.TryGetValue($"Info{i}{info}ID", out var id);
                                    OPTCache.Values.TryGetValue($"Info{i}{info}OrderNo", out var orderNo);
                                    OPTCache.Values.TryGetValue($"Info{i}{info}SheetWidth", out var sheetWidth);
                                    OPTCache.Values.TryGetValue($"Info{i}{info}SheetHeight", out var sheetHeight);
                                    OPTCache.Values.TryGetValue($"Info{i}{info}Customer", out var customer);
                                    var lableArr = label?.Split(";")!;
                                    if (lableArr != null)
                                    {
                                        builder.Append(
                                       $"\"X\":{x},\"Y\":{y},\"Type\":\"OPT\", \"ID\":{id},\"Info\":1,\"Position\":{lableArr[4] ?? "1"},\"OrderNo\":\"{orderNo}\",\"SheetWidth\":{sheetWidth},\"SheetHeight\":{sheetHeight},\"Customer\":\"{customer}\"");
                                    }
                                    else
                                    {
                                        builder.Append(
                                                       $"\"X\":{x},\"Y\":{y},\"Type\":\"OPT\", \"ID\":{id},\"Info\":1,\"Position\":1,\"OrderNo\":\"{orderNo}\",\"SheetWidth\":{sheetWidth},\"SheetHeight\":{sheetHeight},\"Customer\":\"{customer}\"");
                                    }
                                    builder.Append("},");
                                }

                                if ((k + count1) < arrPos.Length && !arrPos[k + count1].Contains("Info") && arrPos[k + count1].Split("=")[0] == arrPos[k + count1 - 1].Split("=")[0])
                                {
                                    if (arrPos[k + count1].Split("=")[1] == "Z")
                                    {
                                        x += System.Convert.ToDouble(arrPos[k + count1].Split("=")[1]);
                                    }
                                }
                                k = k + count1;
                            }
                        }

                        builder.Append("],");
                    }

                    if (points != null)
                    {
                        builder.Append($"\"Points\":[");
                        var arrPos = points.Split(",");
                        for (var j = 0; j < arrPos.Length; j++)
                        {
                            if (string.IsNullOrEmpty(arrPos[j]))
                            {
                                continue;
                            }

                            var arr = arrPos[j].Split(" ");

                            for (int k = 0; k < arr.Length; k++)
                            {
                                if (arr[k].Contains("x="))
                                {
                                    builder.Append("{");
                                    builder.Append($"\"X\":{arr[k].Replace("x=", " ")}, ");
                                }

                                if (arr[k].Contains("y="))
                                {
                                    builder.Append($"\"Y\":{arr[k].Replace("y=", " ")}, ");
                                }

                                if (arr[k].Contains("X="))
                                {
                                    builder.Append($"\"X1\":{arr[k].Replace("X=", " ")}, ");
                                }

                                if (arr[k].Contains("Y="))
                                {
                                    builder.Append($"\"Y1\":{arr[k].Replace("Y=", " ")} ");
                                    builder.Append("},");
                                }
                            }
                        }

                        builder.Append("]");
                    }

                    builder.Append("},");
                }

                builder.Append("]}");
                try
                {
                    pos = JsonSerializer.Deserialize<OriginalInfo>(builder.ToString(),
                        new JsonSerializerOptions()
                        {
                            PropertyNameCaseInsensitive = false,
                            AllowTrailingCommas = true,
                            NumberHandling = JsonNumberHandling.AllowReadingFromString |
                                             JsonNumberHandling.WriteAsString
                        });
                }
                catch (Exception)
                {
                    throw;
                }
            }

            return pos ?? new OriginalInfo();
        }
    }
}
